package designpatterns.behavior;

/**
 * 访问者模式：主要将数据结构与数据操作分离。（数据元素相对稳定而访问方式多种多样的数据结构）
 * 优点： 1、符合单一职责原则。 2、优秀的扩展性。 3、灵活性。
 * 缺点：1、具体元素对访问者公布细节，违反了迪米特原则。
 * 2、具体元素变更比较困难。
 * 3、违反了依赖倒置原则，依赖了具体类，没有依赖抽象。
 * 使用场景：1、对象结构中对象对应的类很少改变，但经常需要在此对象结构上定义新的操作。
 * 2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作，而需要避免让这些操作"污染"这些对象的类，
 * 也不希望在增加新操作时修改这些类。
 *
 * @author jack.wu
 * @since 2019/12/6 16:43
 */
public class Visitor {
    public static void main(String[] args) {
        ComputerPart computer = new Computer();
        computer.accept(new ComputerPartDisplayVisitor());
    }
}

interface ComputerPartVisitor {
    void visitor(Computer computer);

    void visitor(Mouse mouse);

    void visitor(Keyboard keyboard);

    void visitor(Monitor monitor);
}

interface ComputerPart {
    void accept(ComputerPartVisitor visitor);
}

class Computer implements ComputerPart {

    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visitor(this);
    }
}

class Mouse implements ComputerPart {

    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visitor(this);
    }
}

class Keyboard implements ComputerPart {

    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visitor(this);
    }
}

class Monitor implements ComputerPart {

    @Override
    public void accept(ComputerPartVisitor visitor) {
        visitor.visitor(this);
    }
}

class ComputerPartDisplayVisitor implements ComputerPartVisitor {

    @Override
    public void visitor(Computer computer) {
        System.out.println("Displaying Computer");
    }

    @Override
    public void visitor(Mouse mouse) {
        System.out.println("Displaying Mouse");
    }

    @Override
    public void visitor(Keyboard keyboard) {
        System.out.println("Displaying Keyboard");
    }

    @Override
    public void visitor(Monitor monitor) {
        System.out.println("Displaying Monitor");
    }
}
